Carros de lego, microcontroladores e visão computacional
Thiago Pires | IBM
Thiago Pires
Formação:
Estatística (UERJ)
MSc. Epidemiologia (ENSP/FIOCRUZ)
DSc. Engenharia Biomédica (COPPE/UFRJ)
Experiência profissional:
Pesquisador (FIOCRUZ)
Professor (UFF)
Estatístico (FGV)
Cientista de Dados (CIO/IBM)
TinyML
É uma abreviação para Tiny Machine Learning. Refere-se a uma abordagem de aplicação de modelos de aprendizado de máquina em dispositivos de recurso computacional limitado, como microcontroladores, microprocessadores e sistemas embarcados.
Microcontroladores
Microcontroladores
É um pequeno computador num único circuito integrado
Contendo um núcleo de processador
Memória
Periféricos programáveis de entrada e saída.
WIFI e Bluetooth.
ESP32 é uma série de microcontroladores de baixo custo e baixo consumo de energia.
ATOM Lite
G22, G19, etc: General Purpose Input/Output (GPIO) são portas programáveis de entrada e saída de dados.
I2C, SPI: Protocolos de comunicação.
GND, 3V3, 5V: Energia.
WIFI, Bluetooth
Infravermelho
ATOM Lite da M5Stack
Protocolos de comunicação
I2C
O protocolo I2C (Inter-Integrated Circuit) é uma das interfaces de comunicação serial mais antigas e amplamente usadas no mundo da eletrônica. Sua história remonta à década de 1980, quando foi desenvolvido pela Philips
sequenceDiagram
participant Master as Microcontrolador
participant Slave as Periférico
Master->>Slave: Microcontrolador inicia comunicação
note over Master,Slave: SDA muda de alta para baixa voltagem antes do SCL
Master->>Slave: Envio do endereço do periférico (7 bits)
note over Master,Slave: Inclusão R/W bit (0 para escrita)
Slave->>Master: Acknowledge (ACK)
note over Slave,Master: Reconhecimento do periférico com um bit
Master->>Slave: Envio de dados
note over Master,Slave: 8 bits
Slave->>Master: Acknowledge (ACK)
note over Slave,Master: Periférico reconhece
Master-->>Slave: Condição de parada
note over Slave,Master: SDA muda de baixa para alta voltagem após o SCL
Protocolos de comunicação
UART
O protocolo UART (Universal Asynchronous Receiver/Transmitter)
sequenceDiagram
participant DispositivoA as Dispositivo A (Transmissor)
participant DispositivoB as Dispositivo B (Receptor)
DispositivoA->>DispositivoB: Início da Comunicação UART
DispositivoA->>DispositivoB: TX para o RX
note over DispositivoA, DispositivoB: TX de um dispositivo <br> transmite para o RX do outro
DispositivoA-->>DispositivoB: Fim da Comunicação UART
Linguagens de programação para o ESP32
C, C++
Python (Micropython)
Rust
Go (TinyGo)
Javascript (Espruino)
NuttX (SO)
Lego Mindstorms agora aceita Python
Lego Technic
LEGO Technic é um tema de produtos LEGO voltada para a criação de modelos mais complexos, com o recurso a blocos e peças mais sofisticados do que os das linhas básica e temáticas de LEGO
Peças do Lego Technic
Triciclo Reverso
Controle remoto via socket
Esquema do controle remoto
Controle remoto via socket
atom_motion.py
import machineimport structimport networkimport socketimport neopixelimport utime# setup uartuart = machine.UART(1, tx=19, rx=22)uart.init(115200, bits=8, parity=None, stop=1)# setup lednp = neopixel.NeoPixel(machine.Pin(27), 1)# setup servo and motorsda_pin = machine.Pin(25)scl_pin = machine.Pin(21)i2c = machine.I2C(0, sda=sda_pin, scl=scl_pin, freq=400000)devices = i2c.scan()device = [i for i in devices ifhex(i) =='0x38'][0]def set_speed(speed): buf =bytearray(1) struct.pack_into('b', buf, 0, speed) i2c.writeto_mem(device, 0, buf)def set_angle(angle): buf =bytearray(1) struct.pack_into('b', buf, 0, angle) i2c.writeto_mem(device, 2, buf)def set_direction(x):if x >200: set_angle(65)elif x <50: set_angle(115)else: set_angle(90)def set_run(x):if x >200: set_speed(127)elif x <50: set_speed(0)else: set_speed(86)# create access-pointap = network.WLAN(network.AP_IF)ap.config(essid='ATOM-MOTION')ap.config(max_clients=10)ap.active(True)# create server socketserver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)server.bind(('', 12000))whileTrue:try: status =int(uart.read(1).decode())if status ==1: np[0] = (0,0,255) np.write()elif status ==0: np[0] = (0, 255, 0) np.write() direction, address_client = server.recvfrom(2048) out = struct.unpack('BBB', direction) set_direction(out[0]) set_run(out[1])print(out)else: np[0] = (255, 0, 0) np.write()print(status)except:pass utime.sleep_ms(500)